/**
 * 
 */
package edu.towson.cosc.cosc455.jirani2.compiler;

import edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer;

/**
 * @author jirani2
 * Lexical Analyzer is for the purpose of breaking up each piece
 * of the .lol input file char by char, and then determining
 * if the tokens are legal or not
 */
public class MyLexicalAnalyzer implements LexicalAnalyzer {

	/** stores next character */
	public static String nextCharacter = "";
	/** current tag token */
	public static String currentToken = "";
	/** Current text token */
	public static String currentText = "";
	/** Position that has curr char */
	public static int currentPosition;
	/**  To index fileString of .lol */
	public static char[] currString;
	/** Hold current char to be added */
	public static char currChar; 
	
	
	/**
	 * Gets next character from the the input. Determines whether
	 * it is a token, text, or just space
	 */
	@Override
	public void getNextToken() {
		char c;
		
		getCharacter();//Since void, using static 'currChar' as return
		c = currChar;
		while(c == ' '){//Checking while the character is a space
			getCharacter();//Keeping getting char until we hit text
			c = currChar;
		}
		if(c == '#'){//If # we know it is a potential token
			currentToken += c;//Add to current token and start to process
			processTag();
			
		}else if(isText(c)){//If it is text
			currentText += c;
			processText();//Process as text
		}else{
			System.err.println("LEXICAL ERROR " + c + " is not a legal token!");
		}
		currentToken = "";//Resetting token
		currentText = "";
	}
	
	/**
	 * 
	 *	Tests if legal text, but you said in lecture
	 *  We can assume legal text
	 */

	public boolean isText(char text){
		//Im gonna assume you'll put in valid text for now,
		//And not throw me any foreign characters, but you 
		//clearly see that i would check :)
		return true;
	}
	
	/** Processes the text of a .lol file */
	public void processText(){
		char c;
		getCharacter();//Get next char 
		c = currChar;
		currentText += c;//Contact onto current Text
		//Makes sure it is not an attempt to make tag and that
		//it does not read past the length of file, if so keeping concatinating
		while(c != '#' && currentPosition < MyCompiler.fileContents.length()){
			getCharacter();
			c = currChar;
			currentText += c;
		}
		if(c == '#'){//IF it is beginning of tag, return back and begin to process
			currentText = currentText.substring(0, currentText.length() -1);
			currentPosition--;
		}
		LexicalTokens.textDictionary.add(currentText);//Adding as text
		MyCompiler.parseTree.add(currentText);//Adding to parseTree
		
		MyCompiler.token = currentText;//Letting current token equal to the text
		return;
	}
	
	/** Processes the tag of a .lol file */
	public void processTag(){
		char c;
		getCharacter();
		c = currChar;
		currentToken += c;
		while(c != ' '){ //Ignore white space, iterate while valid text
			getCharacter();
			c = currChar;
			currentToken += c;//Will add one extra space at end which will be removed
		}
		currentToken = currentToken.substring(0, currentToken.length() -1);//Remove space at end
		
		//Looking for single tag token, if so, add to parse tree and return
		if(lookupToken()){
			MyCompiler.token = currentToken;
			MyCompiler.parseTree.add(currentToken);
			return;
		}
		currentToken += " ";//Adding space to view a 2 tag token
		getCharacter();
		c = currChar;
		currentToken += c;
		while(c != ' '){//Keep adding until there is a space
			getCharacter();
			c = currChar;
			currentToken += c;
		}
		//To remove extra space
		currentToken = currentToken.substring(0, currentToken.length() -1);
		
		//When there is a space, lookup to see if a two tag token, if so add to tree
		if(lookupToken()){
			MyCompiler.token = currentToken;
			MyCompiler.parseTree.add(currentToken);
			return;
		}
		currentToken += " ";
		getCharacter();
		c = currChar;
		currentToken += c;
		while(c != ' '){
			getCharacter();
			c = currChar;
			currentToken += c;
		}
		//Remove space
		currentToken = currentToken.substring(0, currentToken.length() -1);
		//Look to see if three tag token, of so add and return
		if(lookupToken()){
			MyCompiler.token = currentToken;
			MyCompiler.parseTree.add(currentToken);
			return;
		}
		//If there is a #, with no valid token tag, then error
		currentToken += " ";
		System.err.println("LEXICAL ERROR: You have an invalid token " + currentToken);
		System.exit(0);
	}

	/** Gets char by char from the .lol file String */
	@Override
	public void getCharacter() {
		currString = MyCompiler.fileContents.toCharArray();//Convert to index through
		if(currentPosition < currString.length){
			currChar = currString[currentPosition];
			currentPosition++;
		}
	}


	@Override
	public void addCharacter() {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isSpace(String c) {
		// TODO Auto-generated method stub
		return false;
	}


	/** Looks to see if full token is in the list of defined tokens */
	@Override
	public boolean lookupToken() {
		if(LexicalTokens.lexTokens.contains(currentToken.toUpperCase())){
			return true;
		}else{
			return false;
		}
	}
}
